home *** CD-ROM | disk | FTP | other *** search
/ Aminet 31 / Aminet 31 (1999)(Schatztruhe)[!][Jun 1999].iso / Aminet / util / gnu / xpdf-0.8-src.lha / xpdf-0.8-src / ltk / LTKApp.cc < prev    next >
C/C++ Source or Header  |  1998-11-28  |  13KB  |  477 lines

  1. //========================================================================
  2. //
  3. // LTKApp.cc
  4. //
  5. // Copyright 1996 Derek B. Noonburg
  6. //
  7. //========================================================================
  8.  
  9. #ifdef __GNUC__
  10. #pragma implementation
  11. #endif
  12.  
  13. #include <stdlib.h>
  14. #include <stddef.h>
  15. #include <unistd.h>
  16. #ifdef HAVE_STRINGS_H
  17. // needed by AIX for bzero() declaration for FD_ZERO
  18. #include <strings.h>
  19. #endif
  20. #ifdef HAVE_BSTRING_H
  21. // needed by IRIX for bzero() declaration for FD_ZERO
  22. #include <bstring.h>
  23. #endif
  24. #ifdef HAVE_SYS_SELECT_H
  25. // needed by some systems for fd_set
  26. #include <sys/select.h>
  27. #endif
  28. #ifdef HAVE_SYS_BSDTYPES_H
  29. // needed by some systems for fd_set
  30. #include <sys/bsdtypes.h>
  31. #endif
  32. #include <X11/Xlib.h>
  33. #include <X11/Xutil.h>
  34. #include <X11/Xatom.h>
  35. #include "gtypes.h"
  36. #include "LTKApp.h"
  37. #include "LTKResources.h"
  38. #include "LTKWindow.h"
  39. #include "LTKMenu.h"
  40. #include "LTKMisc.h"
  41. #include "LTKWidget.h"
  42.  
  43. #ifdef XlibSpecificationRelease
  44. #if XlibSpecificationRelease < 5
  45. typedef char *XPointer;
  46. #endif
  47. #else
  48. typedef char *XPointer;
  49. #endif
  50.  
  51. #ifdef VMS
  52. extern "C" int XMultiplexInput(int num_displays,
  53.                    Display *displays[],
  54.                    unsigned long ef_mask,
  55.                    unsigned long timeout,
  56.                    unsigned long options,
  57.                    long *retval_pointer);
  58. #if defined(__DECCXX) && (_VMS_VER < 70000000)
  59. extern "C" int gettimeofday (struct timeval *__tp, void *__tzp);
  60. #endif
  61. #endif
  62.  
  63. //------------------------------------------------------------------------
  64.  
  65. #define ltkSingleClickTime 200    // max time from press to release for
  66.                 //   a single click (in ms)
  67.  
  68. #define ltkDoubleClickTime 200    // max time from press to press for a
  69.                 //   double click (in ms)
  70.  
  71. //------------------------------------------------------------------------
  72. // LTKApp
  73. //------------------------------------------------------------------------
  74.  
  75. LTKApp::LTKApp(char *appName1, XrmOptionDescRec *opts,
  76.            int *argc, char *argv[]) {
  77.   int numOpts;
  78.   XrmDatabase cmdLineDB;
  79.   GString *displayName;
  80.   int h;
  81.  
  82.   appName = new GString(appName1);
  83.   windows = NULL;
  84.   for (h = 0; h < ltkWinTabSize; ++h)
  85.     winTab[h] = NULL;
  86.   grabWin = NULL;
  87.   activeMenu = NULL;
  88.   repeatWidget = NULL;
  89.   repeatDelay = 0;
  90.   repeatPeriod = 0;
  91.   firstRepeat = gTrue;
  92.   cmdLineDB = NULL;
  93.   resourceDB = NULL;
  94.   XrmInitialize();
  95.   for (numOpts = 0; opts[numOpts].option; ++numOpts) ;
  96.   ltkGetCmdLineResources(&cmdLineDB, opts, numOpts, appName, argc, argv);
  97.   displayName = ltkGetStringResource(cmdLineDB, appName, "display", "");
  98.   if (!(display = XOpenDisplay(displayName->getCString()))) {
  99.     ltkError("Cannot connect to X server %s\n",
  100.          XDisplayName(displayName->getCString()));
  101.     exit(1);
  102.   }
  103.   delete displayName;
  104.   screenNum = DefaultScreen(display);
  105.   ltkGetOtherResources(display, cmdLineDB, &resourceDB);
  106.   wmDeleteWinAtom = XInternAtom(display, "WM_DELETE_WINDOW", False);
  107.   pressedBtn = 0;
  108.   killCbk = NULL;
  109. }
  110.  
  111. LTKApp::~LTKApp() {
  112.   LTKWindow *w1;
  113.  
  114.   while (windows) {
  115.     w1 = windows;
  116.     windows = windows->getNext();
  117.     delete w1;
  118.   }
  119.   XCloseDisplay(display);
  120.   delete appName;
  121. }
  122.  
  123. GString *LTKApp::getStringResource(char *inst, char *def) {
  124.   return ltkGetStringResource(resourceDB, appName, inst, def);
  125. }
  126.  
  127. int LTKApp::getIntResource(char *inst, int def) {
  128.   return ltkGetIntResource(resourceDB, appName, inst, def);
  129. }
  130.  
  131. GBool LTKApp::getBoolResource(char *inst, GBool def) {
  132.   return ltkGetBoolResource(resourceDB, appName, inst, def);
  133. }
  134.  
  135. unsigned long LTKApp::getColorResource(char *inst,
  136.                        char *def1, unsigned long def2,
  137.                        XColor *xcol) {
  138.   return ltkGetColorResource(resourceDB, appName, inst,
  139.                  display, screenNum, def1, def2, xcol);
  140. }
  141.  
  142. XFontStruct *LTKApp::getFontResource(char *inst,  char *def) {
  143.   return ltkGetFontResouce(resourceDB, appName, inst, display, screenNum, def);
  144. }
  145.  
  146. void LTKApp::getGeometryResource(char *inst, int *x, int *y,
  147.                  Guint *width, Guint *height) {
  148.   ltkGetGeometryResource(resourceDB, appName, inst, display, screenNum,
  149.              x, y, width, height);
  150. }
  151.  
  152. LTKWindow *LTKApp::addWindow(LTKWindow *w) {
  153.   w->setNext(windows);
  154.   windows = w;
  155.   return w;
  156. }
  157.  
  158. LTKWindow *LTKApp::delWindow(LTKWindow *w) {
  159.   LTKWindow *w1, *w2;
  160.   int h;
  161.   LTKWinHash *p1, *p2, *p3;
  162.  
  163.   for (w1 = NULL, w2 = windows; w2 && w2 != w; w1 = w2, w2 = w2->getNext()) ;
  164.   if (w2 == w) {
  165.  
  166.     // remove window from window list
  167.     if (w1)
  168.       w1->setNext(w2->getNext());
  169.     else
  170.       windows = w2->getNext();
  171.     w2->setNext(NULL);
  172.  
  173.     // remove window and widgets from hash table
  174.     for (h = 0; h < ltkWinTabSize; ++h) {
  175.       p1 = NULL;
  176.       p2 = winTab[h];
  177.       while (p2) {
  178.     if (p2->win == w) {
  179.       p3 = p2;
  180.       if (p1)
  181.         p2 = p1->next = p2->next;
  182.       else
  183.         p2 = winTab[h] = p2->next;
  184.       delete p3;
  185.     } else {
  186.       p1 = p2;
  187.       p2 = p2->next;
  188.     }
  189.       }
  190.     }
  191.  
  192.     return w2;
  193.   }
  194.   return NULL;
  195. }
  196.  
  197. void LTKApp::registerXWindow(Window xwin, LTKWindow *win, LTKWidget *widget) {
  198.   int h;
  199.   LTKWinHash *p;
  200.  
  201.   h = (int)xwin % ltkWinTabSize;
  202.   p = new LTKWinHash;
  203.   p->xwin = xwin;
  204.   p->win = win;
  205.   p->widget = widget;
  206.   p->next = winTab[h];
  207.   winTab[h] = p;
  208. }
  209.  
  210. LTKWindow *LTKApp::findWindow(Window xwin, LTKWidget **widget) {
  211.   int h;
  212.   LTKWinHash *p;
  213.  
  214.   h = (int)xwin % ltkWinTabSize;
  215.   for (p = winTab[h]; p; p = p->next) {
  216.     if (p->xwin == xwin) {
  217.       *widget = p->widget;
  218.       return p->win;
  219.     }
  220.   }
  221.   *widget = NULL;
  222.   return NULL;
  223. }
  224.  
  225. void LTKApp::setRepeatEvent(LTKWidget *repeatWidget1, int repeatDelay1,
  226.                 int repeatPeriod1) {
  227.   repeatWidget = repeatWidget1;
  228.   repeatDelay = repeatDelay1;
  229.   repeatPeriod = repeatPeriod1;
  230.   firstRepeat = gTrue;
  231.   gettimeofday(&lastRepeat, NULL);
  232. }
  233.  
  234. void LTKApp::doEvent(GBool wait) {
  235. #ifdef VMS
  236.   long delay, retval;
  237. #else
  238.   fd_set readFDs, writeFDs, exceptFDs;
  239. #endif
  240.   struct timeval curTime, timeout;
  241.   int timeout1;
  242.   XEvent event;
  243.   XEvent event2;
  244.   Window pointerRoot, pointerChild;
  245.   LTKWindow *win;
  246.   LTKWidget *widget;
  247.   LTKMenu *menu;
  248.   KeySym key;
  249.   GString *str;
  250.   char buf[20];
  251.   Atom typeRet;
  252.   int formatRet;
  253.   unsigned long length, left;
  254.   unsigned char *bufPtr;
  255.   GBool click, dblClick;
  256.   int x, y, rx, ry;
  257.   unsigned int mask;
  258.   int n, i;
  259.  
  260.   while (XPending(display) == 0) {
  261.     if (!wait)
  262.       return;
  263. #ifndef VMS
  264.     FD_ZERO(&readFDs);
  265.     FD_ZERO(&writeFDs);
  266.     FD_ZERO(&exceptFDs);
  267.     n = ConnectionNumber(display);
  268.     FD_SET(n, &readFDs);
  269. #endif
  270.     if (!repeatWidget) {
  271. #ifdef VMS
  272.       n = XMultiplexInput(1, &display, 0, 0, 0, &retval);
  273. #else // VMS
  274. #ifdef SELECT_TAKES_INT
  275.       n = select(n+1, (int *)&readFDs, (int *)&writeFDs, (int *)&exceptFDs,
  276.          NULL);
  277. #else
  278.       n = select(n+1, &readFDs, &writeFDs, &exceptFDs, NULL);
  279. #endif
  280. #endif // VMS
  281.     } else {
  282.       gettimeofday(&curTime, NULL);
  283.       timeout.tv_sec = curTime.tv_sec - lastRepeat.tv_sec;
  284.       if (curTime.tv_usec < lastRepeat.tv_usec) {
  285.     --timeout.tv_sec;
  286.     timeout.tv_usec = (1000000 + curTime.tv_usec) - lastRepeat.tv_usec;
  287.       } else {
  288.     timeout.tv_usec = curTime.tv_usec - lastRepeat.tv_usec;
  289.       }
  290.       timeout1 = firstRepeat ? repeatDelay : repeatPeriod;
  291.       if (timeout.tv_sec > 0 || timeout.tv_usec > timeout1)
  292.     timeout.tv_usec = 0;
  293.       else
  294.     timeout.tv_usec = timeout1 - timeout.tv_usec;
  295.       timeout.tv_sec = 0;
  296. #ifdef VMS
  297.       if ((delay = timeout.tv_usec / 1000) == 0)
  298.     delay = 1;
  299.       n = XMultiplexInput(1, &display, 0, delay, 0, &retval);
  300. #else // VMS
  301. #ifdef SELECT_TAKES_INT
  302.       n = select(n+1, (int *)&readFDs, (int *)&writeFDs, (int *)&exceptFDs,
  303.          &timeout);
  304. #else
  305.       n = select(n+1, &readFDs, &writeFDs, &exceptFDs, &timeout);
  306. #endif
  307. #endif // VMS
  308.     }
  309.     if (n == 0 && repeatWidget) {
  310.       repeatWidget->repeatEvent();
  311.       firstRepeat = gFalse;
  312.       gettimeofday(&lastRepeat, NULL);
  313.       return;
  314.     }
  315.   }
  316.  
  317.   XNextEvent(display, &event);
  318.   win = findWindow(event.xany.window, &widget);
  319.   if (activeMenu && event.xany.window == activeMenu->getXWindow())
  320.     menu = activeMenu;
  321.   else
  322.     menu = NULL;
  323.   switch (event.type) {
  324.   case Expose:
  325.     // redraw the window or widget, ignoring all but the last
  326.     // Expose event for that window
  327.     if (event.xexpose.count == 0) {
  328.       if (widget)
  329.     widget->redraw();
  330.       else if (win)
  331.     win->redrawBackgro